package main

import (
	"bufio"
	"compress/zlib"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

var loc, _ = time.LoadLocation("Asia/Shanghai")

/*
sub interval
0	7
1	1
2	2
...
6	6
*/
func Timer(timeString string) {
	TIME_FMT := "2006-01-02 15:04:05"
	if date, err := time.ParseInLocation(TIME_FMT, timeString, loc); err != nil {
		fmt.Println("err:", err)
	} else {
		str_format := "20060102150405"
		timeStr := date.Format(str_format)
		fmt.Println(timeStr)
	}
}

func Dater() {
	now := time.Now()
	sub := 6 - int(now.Weekday())
	interval := sub // 下一周距今天隔了几天
	if sub == 0 {
		interval = 7
	}
	firstSatuday := now.Add(time.Duration(interval) * time.Hour * 24)
	fmt.Println(firstSatuday.Format("2006-01-02"))

	for i := 0; i < 3; i++ {
		firstSatuday = firstSatuday.Add(7 * time.Hour * 24)
		fmt.Println(firstSatuday.Format("2006-01-02"))
	}
}

func readFile(inPath string, writer *bufio.Writer, writer2 *zlib.Writer) {
	if fin, err := os.Open(inPath); err != nil {
		fmt.Println(err)
		return
	} else {
		defer fin.Close()
		reader := bufio.NewReader(fin)
		for {
			if line, err := reader.ReadString('\n'); err != nil {
				if err == io.EOF {
					if len(line) > 0 { // 文件最后一行末尾没有换行符
						writer.WriteString(line)
						writer.WriteString("\n")
						writer2.Write([]byte(line))
						writer2.Write([]byte{'\n'})
					}
				}
				break
			} else {
				writer.WriteString(line)
				writer2.Write([]byte(line))
			}
		}
	}
}

func mergeFile(dir string) {
	fout, err := os.OpenFile("big.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fout.Close()

	writer := bufio.NewWriter(fout)

	fout2, err := os.OpenFile("big.zlib", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fout2.Close()

	writer2 := zlib.NewWriter(fout2)

	// 遍历目录下一级子目录
	if files, err := ioutil.ReadDir(dir); err != nil {
		fmt.Println(err)
		return
	} else {
		for _, file := range files {
			if file.IsDir() {
				continue
			}
			baseName := file.Name()
			if strings.HasSuffix(baseName, ".txt") {
				inPath := filepath.Join(dir, baseName)
				readFile(inPath, writer, writer2)
			}
		}
	}

	writer.Flush()
	writer2.Flush()
}

type BufferedFileWriter struct {
	buffer      [1024]byte
	endPos      int
	fileHandler *os.File
}

func NewBufferedFileWriter(fd *os.File) *BufferedFileWriter {
	return &BufferedFileWriter{
		fileHandler: fd,
	}
}

func (writer *BufferedFileWriter) Flush() {
	if writer.endPos > 0 {
		writer.fileHandler.Write(writer.buffer[:writer.endPos])
		fmt.Println("触发了真正写磁盘")
		writer.endPos = 0
	}
}

func (writer *BufferedFileWriter) Write(content []byte) {
	if len(content) >= 1024 {
		writer.Flush()
		writer.fileHandler.Write(content)
	} else {
		if writer.endPos+len(content) >= 1024 {
			writer.Flush()
			writer.Write(content)
		} else {
			copy(writer.buffer[writer.endPos:], content)
			writer.endPos += len(content)
		}
	}
}

func (writer *BufferedFileWriter) WriteString(content string) {
	writer.Write([]byte(content))
}

func main() {
	// 1. 把字符串1998-10-01 08:10:00解析成time.Time，再格式化成字符串199810010810
	fmt.Println("=====第一题=====")
	// timeStr := "1998-10-01 08:10:00"
	// Timer(timeStr)

	// 2. 我们是每周六上课，输出我们未来4次课的上课日期（不考虑法定假日）
	fmt.Println("=====第二题=====")
	// Dater()

	// 3. 把一个目录下的所有.txt文件合一个大的.txt文件，再对这个大文件进行压缩
	fmt.Println("=====第三题=====")
	// mergeFile("./dir")

	// 4. 自己实现一个BufferedFileWriter
	fmt.Println("=====第四题=====")
	fout, err := os.OpenFile("zcy.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fout.Close()

	writer := NewBufferedFileWriter(fout)
	for i := 0; i < 5; i++ {
		writer.WriteString("0123456789\n")
	}
	writer.Flush()
}
